Day11 的文章介紹 JavaScript 中的嚴謹模式 (Strict Mode) 是什麼、如何使用、為什麼要用,並舉了簡單的例子來示範。
嚴謹模式 (Strict Mode) 就像 JavaScript 中的「還我漂亮拳」,能夠讓原本不夠嚴謹、造成混亂的語法,變得更安全、乾淨。
(Source: 網路)
「不允許使用未宣告的變數」只是嚴謹模式最簡單的應用,事實上嚴謹模式發揮的地方非常多。
接下來會用各種例子來檢視嚴謹模式使用前和使用後的效果。
錯誤類型:
ReferenceError: x is not defined
使用前:
x = 3.14;
console.log(x); // 3.14
使用後:
"use strict";
x = 3.14; // ReferenceError: x is not defined
console.log(x);
delete
運算子 (原本對變數或函數作刪除並不會有效果,但也不會拋錯,等於無用的廢 code)錯誤類型:
SyntaxError: Delete of an unqualified identifier in strict mode
使用前:
// variable (沒有作用)
var x = 3.14;
console.log( delete x ); // false
console.log(x); // 3.14
// function via declararion (沒有作用)
function f1(){ console.log('Hi 1'); }
console.log( delete f1 ); // false
console.log(f1); // ƒ f1(){ console.log('Hi 1'); }
// function via expression (沒有作用)
var f2 = function() { console.log('Hi 2'); }
console.log( delete f2 ); // false
console.log(f2); // ƒ () { console.log('Hi 2'); }
// array element
var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log( delete fruits[2] ); // true
console.log(fruits); // ["Banana", "Orange", empty, "Mango"]
// object property
var person = {name: 'John', age:18};
console.log( delete person.name ); // true
console.log(person); // {age: 18}
使用後:
"use strict";
// variable
var x = 3.14;
console.log( delete x ); // SyntaxError: Delete of an unqualified identifier in strict mode.
// function via declararion
function f1(){ console.log('Hi 1'); }
console.log( delete f1 ); // SyntaxError: Delete of an unqualified identifier in strict mode.
// function via expression
var f2 = function() { console.log('Hi 2'); }
console.log( delete f2 ); // SyntaxError: Delete of an unqualified identifier in strict mode.
// array element
var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log( delete fruits[2] ); // true
console.log(fruits); // ["Banana", "Orange", empty, "Mango"]
// object property
var person = {name: 'John', age:18};
console.log( delete person.name ); // true
console.log(person); // {age: 18}
錯誤類型:
SyntaxError: Duplicate parameter name not allowed in this context
使用前:
function myFunc(p1, p1){
console.log(p1);
};
myFunc(10, 20); // 20
使用後:
"use strict";
function myFunc(p1, p1){ // `SyntaxError: Duplicate parameter name not allowed in this context`
console.log(p1);
};
0
,會被直譯為八進制。var x = 010;
等於十進制的 8
。0
(但一般模式下仍可被 JavaScript 直譯器接受)。錯誤類型:
SyntaxError: Octal literals are not allowed in strict mode
使用前:
var n = 010;
console.log(n); // 8
使用後:
"use strict";
var n = 010; // SyntaxError: Octal literals are not allowed in strict mode.
console.log(n);
var x = "\010";
。註:我個人沒用過這個用法,實際上印出來也只看得到空字串,不知道可以應用在哪。
錯誤類型:
SyntaxError: Delete of an unqualified identifier in strict mode.
使用前:
var n = "\010";
console.log(n); // ""
使用後:
"use strict";
var n = "\010"; // SyntaxError: Octal escape sequences are not allowed in strict mode.
console.log(n);
writable:false
的屬性作賦值動作,不會寫入成功,但也不會報錯 (等於廢 code)。錯誤類型:
TypeError: Cannot assign to read only property 'articleTarget' of object '#<Object>'
使用前:
var player = {};
Object.defineProperty(player, "nickname", {value:"OneJar", writable:true});
Object.defineProperty(player, "articleTarget", {value:30, writable:false});
console.log(player); // {nickname: "OneJar", articleTarget: 30}
player.articleTarget = 100;
console.log(player); // {nickname: "OneJar", articleTarget: 30}
使用後:
"use strict";
var player = {};
Object.defineProperty(player, "nickname", {value:"OneJar", writable:true});
Object.defineProperty(player, "articleTarget", {value:30, writable:false});
console.log(player); // {nickname: "OneJar", articleTarget: 30}
player.articleTarget = 100; // TypeError: Cannot assign to read only property 'articleTarget' of object '#<Object>'
console.log(player);
錯誤類型:
TypeError: Cannot set property age of #<Object> which has only a getter
使用前:
var person = {get age() {return 18} };
console.log(person); // {}
console.log(person.age); // 18
person.age = 70;
console.log(person.age); // 18
使用後:
"use strict";
var person = {get age() {return 18} };
console.log(person); // {}
console.log(person.age); // 18
person.age = 70; // TypeError: Cannot set property age of #<Object> which has only a getter
console.log(person.age);